importlib 模块: 图像处理模块
1. PIL的安装
pip3 install pillow -i https://pypi.douban.com/simple # 使用豆瓣的镜像
2. Image
- 生成一个纯色背景图片对象
- 语法: Image.new(mode='模式', size=尺寸, color=RGB色值 或 颜色的英文单词) -> Image.new('RGB', (245, 34), (255, 255, 0))
img_obj = Image.new('RGB', (245, 34), get_random_color()) # 生成一个图片对象
3. ImageDraw
- 生成一个图像画笔对象
- 作用: 一般用于在纯色背景图片对象上添加文字,画点或画线等
- 语法: ImageDraw.Draw(图片对象)
draw_obj = ImageDraw.Draw(img_obj) # 生成一个图片画笔对象
3. ImageFont
- 加载字体文件得到一个字体对象
- 作用: 一般用于在纯色背景图片对象上添加文字
- 语法: ImageFont.truetype('字体文件路径', 字体大小) -> ImageFont.truetype('blog/static/font/kumo.ttf', 28)
font_obj = ImageFont.truetype('blog/static/font/kumo.ttf', 28)
4. 在图片对象上添加文字
- 语法: 图像画笔对象.text(xy=坐标, text='需要添加的文字', fill=RGB色值 或 颜色的英文单词, font=文字对象)
图像画笔对象.text(xy=(0, 0), text='文字', fill=(0, 0, 0), font=font_obj)
from PIL import Image, ImageDraw, ImageFont
img_obj = Image.new('RGB', (245, 34), (255, 255, 0)) # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj) # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28) # 加载字体文件得到一个字体对象
draw_obj.text(xy=(0, 0), text='文字', fill=(0, 0, 0), font=font_obj) # 在图片对象上添加文字
5. 在图片对象上画弧线
- 语法: 图像画笔对象.arc(xy=(num_x, num_y, num_x2, num_y2), start=num, end=num, fill=RGB色值 或 颜色的英文单词)
图像画笔对象.arc((50, 50, 100, 100), 0, 270, fill=(0, 0, 0))
- 参数说明:
- xy 坐标: 需要传递两个点的xy坐标
- start 和 end: 是确定弧度的值
from PIL import Image, ImageDraw, ImageFont
img_obj = Image.new('RGB', (500, 500), (255, 255, 0)) # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj) # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28) # 加载字体文件得到一个字体对象
draw_obj.arc((50, 50, 100, 100), 0, 270, fill=(0, 0, 0)) # 在图片对象上画弧线
6. 在图片对象上画线
- 语法: 图像画笔对象.line(xy=(num_x, num_y, num_x2, num_y2), fill=RGB色值 或 颜色的英文单词)
图像画笔对象.line((10, 10, 100, 100), fill=(0, 0, 0))
- 参数说明:
- xy 坐标: 需要传递两个点的xy坐标,因为两点确定一条直线
from PIL import Image, ImageDraw, ImageFont
img_obj = Image.new('RGB', (500, 500), (255, 255, 0)) # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj) # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28) # 加载字体文件得到一个字体对象
draw_obj.line((10, 10, 100, 100), fill=(0, 0, 0)) # 在图片对象上画线
7. 将图片对象保存到文件中或内存中
- 语法: 图片对象.save(文件句柄, '图片格式')
- 将图片对象保存到文件中,并且生成一张图片
- 注意: 使用bytes类型写入,因为将图片发送给浏览器时需要发送bytes类型的数据
from PIL import Image, ImageDraw, ImageFont
image = Image.new('RGB', (245, 34), (255, 255, 0)) # 生成一个图片对象
f = open('valid_code.png', 'wb')
image.save(f, 'png') # 使用图片对象中的save方法,生成一张图片
f = open('valid_code.png', 'rb')
data = f.read() # 读取图片
- 将图片对象保存到内存中
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
image = Image.new('RGB', (245, 34), (255, 255, 0)) # 生成一个图片对象
io_obj = BytesIO() # 生成一个内存对象,相当于文件句柄
image.save(io_obj, 'png') # 将图片保存到内存中
data = io_obj.getvalue() # 从io对象里面取上一步保存的数据
io_obj.close() # 关闭
8. Django的相关操作
- 将通过PIL模块生成的图片发送给浏览器
# views.py
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
def views_fn(request):
image = Image.new('RGB', (245, 34), (255, 255, 0)) # 生成一个图片对象
io_obj = BytesIO() # 生成一个内存对象,相当于文件句柄
image.save(io_obj, 'png') # 将图片保存到内存中
data = io_obj.getvalue() # 从io对象里面取上一步保存的数据
io_obj.close() # 关闭
return HttpResponse(data) # 将bytes类型数据的图片发送给浏览器
9. 生成一个图片验证码
# views.py
import random
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from django.shortcuts import render, redirect, HttpResponse
def get_vaild_img(request):
# 随机生成RGB色值
def get_random_color():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
img_obj = Image.new('RGB', (245, 34), get_random_color()) # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj) # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28) # 加载字体文件得到一个字体对象
# 生成验证码的随机字符串并且写在图片上
tmp_list = []
for i in range(5):
u = chr(random.randint(65, 90)) # 生成大写字母
l = chr(random.randint(97, 122)) # 生成小写字母
n = str(random.randint(0, 9)) # 生成数字,注意要转换成字符串类型
tmp = random.choice([u, l, n]) # 随机返回一个大小写字母或数字
tmp_list.append(tmp)
draw_obj.text((25 + 45 * i, 0), tmp, fill=get_random_color(), font=font_obj)
request.session['valid_str'] = ''.join(tmp_list) # 将随机生成的字符串写入session中,用于登陆判断
# 给验证图片添加干扰线
width = 245 # 图片宽度(防止越界)
height = 34 # 图片宽度(防止越界)
for i in range(5):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
# 给验证图片添加干扰点
for i in range(40):
draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
x = random.randint(0, width)
y = random.randint(0, height)
draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
# 在内存中生成图片
io_obj = BytesIO() # 生成一个内存对象,相当于文件句柄
img_obj.save(io_obj, 'png')
data = io_obj.getvalue() # 从io对象里面取上一步保存的数据
io_obj.close() # 关闭
return HttpResponse(data) # 将bytes类型数据的图片发送给浏览器